package com.zhoux.springbucks;

import com.github.pagehelper.PageInfo;
import com.zhoux.springbucks.model.Coffee;
import com.zhoux.springbucks.service.CoffeeService;
import com.zhoux.springbucks.service.CoffeeService2;
import io.lettuce.core.ReadFrom;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.RowBounds;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.data.redis.LettuceClientConfigurationBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@SpringBootApplication
@EnableTransactionManagement
@Slf4j
@EnableJpaRepositories
public class SpringbucksApplication implements ApplicationRunner {

	@Autowired
	private CoffeeService coffeeService;
	@Autowired
	private CoffeeService2 coffeeService2;

	public static void main(String[] args) {
		SpringApplication.run(SpringbucksApplication.class, args);
	}

	@Override
	public void run(ApplicationArguments args) throws Exception {
		log.info("----------------查询所有coffee数据----------------------");
		//coffeeService.findAllCoffee();
		coffeeService2.findAllCoffee();

		//generateArtifacts();
		log.info("----------------新增coffee数据----------------------");
		Coffee espresso = new Coffee()
				.withName("espresso1")
				.withPrice(Money.of(CurrencyUnit.of("CNY"), 20.0))
				.withCreateTime(new Date())
				.withUpdateTime(new Date());
		//coffeeService.creatOneCoffee(espresso);
		coffeeService2.creatOneCoffee(espresso);
		Coffee espresso2 = new Coffee()
				.withName("latte")
				.withPrice(Money.of(CurrencyUnit.of("CNY"), 50.0))
				.withCreateTime(new Date())
				.withUpdateTime(new Date());
		//coffeeService.creatOneCoffee(espresso);
		coffeeService2.creatOneCoffee(espresso2);
		Coffee espresso3 = new Coffee()
				.withName("capuccino")
				.withPrice(Money.of(CurrencyUnit.of("CNY"), 30.0))
				.withCreateTime(new Date())
				.withUpdateTime(new Date());
		//coffeeService.creatOneCoffee(espresso);
		coffeeService2.creatOneCoffee(espresso3);
		Coffee espresso4 = new Coffee()
				.withName("mocha")
				.withPrice(Money.of(CurrencyUnit.of("CNY"), 90.0))
				.withCreateTime(new Date())
				.withUpdateTime(new Date());
		//coffeeService.creatOneCoffee(espresso);
		coffeeService2.creatOneCoffee(espresso4);
		Coffee espresso5 = new Coffee()
				.withName("macchiato")
				.withPrice(Money.of(CurrencyUnit.of("CNY"), 120.0))
				.withCreateTime(new Date())
				.withUpdateTime(new Date());
		//coffeeService.creatOneCoffee(espresso);
		coffeeService2.creatOneCoffee(espresso5);
		log.info("----------------查询新增之后的单条coffee数据----------------------");
		//coffeeService.findOneCoffee(1L);
		coffeeService2.findOneCoffee(1L);
		log.info("----------------修改coffee数据----------------------");
		Coffee upCoffee = new Coffee().withId(1L)
				.withName("espresso")
				.withPrice(Money.of(CurrencyUnit.of("CNY"), 30.0))
				.withCreateTime(new Date())
				.withUpdateTime(new Date());
		//coffeeService.updateOneCoffee(upCoffee);
		coffeeService2.updateOneCoffee(upCoffee);
		log.info("----------------查询修改后的单条coffee数据----------------------");
		//coffeeService.findOneCoffee(1L);
		coffeeService2.findOneCoffee(1L);
		log.info("----------------查询所有coffee数据----------------------");
		//coffeeService.findAllCoffee();
		coffeeService2.findAllCoffee();
		log.info("----------------删除单条coffee数据----------------------");
		//coffeeService.delOneCoffee(1L);
		coffeeService2.delOneCoffee(1L);
		log.info("----------------查询删除后的单条coffee数据----------------------");
		//coffeeService.findOneCoffee(1L);
		coffeeService2.findOneCoffee(1L);
		log.info("----------------查询所有coffee数据----------------------");
		//coffeeService.findAllCoffee();
		coffeeService2.findAllCoffee();
		log.info("----------------第一种分页查询coffee数据----------------------");
		coffeeService2.pageFind(1,1).forEach(c -> log.info("Page(1) Coffee {}", c));
		List<Coffee> list = coffeeService2.pageFind(2,3);
		PageInfo page = new PageInfo(list);
		log.info("PageInfo: {}", page);
		log.info("----------------第2种分页查询coffee数据----------------------");
		coffeeService2.pageFind2(new RowBounds(0,3)).forEach(c -> log.info("Page(1) Coffee {}", c));
		coffeeService2.pageFind2(new RowBounds(1,1)).forEach(c -> log.info("Page(2) Coffee {}", c));
	}

	private void generateArtifacts() throws Exception {
		List<String> warnings = new ArrayList<>();
		ConfigurationParser cp = new ConfigurationParser(warnings);
		Configuration config = cp.parseConfiguration(
				this.getClass().getResourceAsStream("/generatorConfig.xml"));
		DefaultShellCallback callback = new DefaultShellCallback(true);
		MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
		myBatisGenerator.generate(null);

		if (warnings.isEmpty()) {
			log.info("文件生成成功");
		} else {
			log.error(warnings.get(0));
		}
	}

    @Bean
    public RedisTemplate<String, Coffee> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Coffee> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    public LettuceClientConfigurationBuilderCustomizer customizer() {
        return builder -> builder.readFrom(ReadFrom.MASTER_PREFERRED);
    }
}
